#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
视觉分析结果管理器模块
负责保存、加载和管理视频分析结果
"""

import os
import json
import time
import shutil
from datetime import datetime
from typing import Dict, Any, List, Optional
import hashlib


class AnalysisResultManager:
    """
    视觉分析结果管理器
    提供分析结果的持久化存储、检索和管理功能
    """
    
    def __init__(self, storage_dir: str = "./analysis_results"):
        """
        初始化分析结果管理器
        
        Args:
            storage_dir: 结果存储目录
        """
        self.storage_dir = storage_dir
        self.index_file = os.path.join(storage_dir, "index.json")
        self._ensure_directories()
        self._init_index()
    
    def _ensure_directories(self):
        """
        确保存储目录存在
        """
        if not os.path.exists(self.storage_dir):
            os.makedirs(self.storage_dir)
            
        # 创建子目录
        subdirs = ["completed", "pending", "failed", "temp"]
        for subdir in subdirs:
            subdir_path = os.path.join(self.storage_dir, subdir)
            if not os.path.exists(subdir_path):
                os.makedirs(subdir_path)
    
    def _init_index(self):
        """
        初始化索引文件
        """
        if not os.path.exists(self.index_file):
            index_data = {
                "version": "1.0",
                "created_at": datetime.now().isoformat(),
                "last_updated": datetime.now().isoformat(),
                "total_results": 0,
                "results": {}
            }
            self._save_index(index_data)
    
    def _load_index(self) -> Dict[str, Any]:
        """
        加载索引文件
        
        Returns:
            Dict[str, Any]: 索引数据
        """
        try:
            with open(self.index_file, 'r', encoding='utf-8') as f:
                return json.load(f)
        except Exception as e:
            print(f"加载索引文件失败: {str(e)}")
            return {"results": {}}
    
    def _save_index(self, index_data: Dict[str, Any]):
        """
        保存索引文件
        
        Args:
            index_data: 索引数据
        """
        try:
            index_data["last_updated"] = datetime.now().isoformat()
            with open(self.index_file, 'w', encoding='utf-8') as f:
                json.dump(index_data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存索引文件失败: {str(e)}")
    
    def save_analysis_result(self, video_id: str, 
                           result: Dict[str, Any],
                           status: str = "completed") -> str:
        """
        保存分析结果
        
        Args:
            video_id: 视频ID
            result: 分析结果
            status: 状态 (completed, pending, failed)
            
        Returns:
            str: 保存的文件路径
        """
        # 确保结果包含基本信息
        if "video_id" not in result:
            result["video_id"] = video_id
        
        if "analysis_time" not in result:
            result["analysis_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        if "status" not in result:
            result["status"] = status
        
        # 生成结果文件路径
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        result_filename = f"{video_id}_{timestamp}.json"
        result_dir = os.path.join(self.storage_dir, status)
        result_path = os.path.join(result_dir, result_filename)
        
        # 保存结果文件
        try:
            with open(result_path, 'w', encoding='utf-8') as f:
                json.dump(result, f, ensure_ascii=False, indent=2)
            
            # 更新索引
            self._update_index(video_id, result_path, status)
            
            print(f"分析结果已保存: {result_path}")
            return result_path
            
        except Exception as e:
            print(f"保存分析结果失败: {str(e)}")
            raise
    
    def load_analysis_result(self, video_id: str) -> Optional[Dict[str, Any]]:
        """
        加载分析结果
        
        Args:
            video_id: 视频ID
            
        Returns:
            Optional[Dict[str, Any]]: 分析结果，如果不存在返回None
        """
        # 从索引中查找
        index_data = self._load_index()
        
        if video_id not in index_data.get("results", {}):
            return None
        
        # 获取最新的结果文件路径
        result_info = index_data["results"][video_id]
        result_path = result_info.get("latest_path")
        
        if not result_path or not os.path.exists(result_path):
            return None
        
        # 加载结果文件
        try:
            with open(result_path, 'r', encoding='utf-8') as f:
                result = json.load(f)
            
            # 添加元数据
            result["_metadata"] = {
                "file_path": result_path,
                "created_at": result_info.get("created_at"),
                "updated_at": result_info.get("updated_at")
            }
            
            return result
            
        except Exception as e:
            print(f"加载分析结果失败: {str(e)}")
            return None
    
    def get_result_history(self, video_id: str) -> List[Dict[str, Any]]:
        """
        获取视频的分析历史
        
        Args:
            video_id: 视频ID
            
        Returns:
            List[Dict[str, Any]]: 分析历史列表
        """
        index_data = self._load_index()
        
        if video_id not in index_data.get("results", {}):
            return []
        
        result_info = index_data["results"][video_id]
        history_paths = result_info.get("history", [])
        
        history = []
        for path_info in history_paths:
            file_path = path_info["path"]
            if os.path.exists(file_path):
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        result = json.load(f)
                    
                    # 添加元数据
                    result["_metadata"] = {
                        "file_path": file_path,
                        "created_at": path_info.get("created_at"),
                        "status": path_info.get("status")
                    }
                    
                    history.append(result)
                except Exception as e:
                    print(f"加载历史结果失败: {str(e)}")
        
        # 按时间倒序排序
        history.sort(key=lambda x: x.get("_metadata", {}).get("created_at", ""), reverse=True)
        
        return history
    
    def update_analysis_result(self, video_id: str, 
                             updates: Dict[str, Any],
                             new_status: str = None) -> str:
        """
        更新分析结果
        
        Args:
            video_id: 视频ID
            updates: 更新的数据
            new_status: 新的状态
            
        Returns:
            str: 更新后的文件路径
        """
        # 加载现有结果
        existing_result = self.load_analysis_result(video_id)
        
        if existing_result:
            # 移除元数据，避免写入结果文件
            existing_result.pop("_metadata", None)
            
            # 更新数据
            existing_result.update(updates)
            
            # 更新状态
            if new_status:
                existing_result["status"] = new_status
            
            # 更新时间戳
            existing_result["last_updated"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            
            # 保存更新后的结果
            status = new_status or existing_result.get("status", "completed")
            return self.save_analysis_result(video_id, existing_result, status)
        else:
            # 如果结果不存在，创建新的
            updates["video_id"] = video_id
            updates["analysis_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            if new_status:
                updates["status"] = new_status
            
            return self.save_analysis_result(video_id, updates, new_status or "completed")
    
    def delete_analysis_result(self, video_id: str, delete_history: bool = False) -> bool:
        """
        删除分析结果
        
        Args:
            video_id: 视频ID
            delete_history: 是否删除所有历史记录
            
        Returns:
            bool: 是否删除成功
        """
        index_data = self._load_index()
        
        if video_id not in index_data.get("results", {}):
            return False
        
        try:
            # 获取结果信息
            result_info = index_data["results"][video_id]
            history_paths = result_info.get("history", [])
            
            # 删除文件
            if delete_history:
                # 删除所有历史记录
                for path_info in history_paths:
                    file_path = path_info["path"]
                    if os.path.exists(file_path):
                        os.remove(file_path)
            else:
                # 只删除最新的结果
                latest_path = result_info.get("latest_path")
                if latest_path and os.path.exists(latest_path):
                    os.remove(latest_path)
                    
                    # 将历史中的下一个结果设为最新
                    if history_paths:
                        # 过滤掉已删除的最新结果
                        filtered_history = [p for p in history_paths if p["path"] != latest_path]
                        if filtered_history:
                            # 更新索引中的最新路径
                            index_data["results"][video_id]["latest_path"] = filtered_history[0]["path"]
                            index_data["results"][video_id]["history"] = filtered_history
                        else:
                            # 如果没有历史记录了，移除整个视频条目
                            del index_data["results"][video_id]
            
            # 更新索引
            index_data["total_results"] = len(index_data.get("results", {}))
            self._save_index(index_data)
            
            print(f"分析结果已删除: {video_id}")
            return True
            
        except Exception as e:
            print(f"删除分析结果失败: {str(e)}")
            return False
    
    def list_all_results(self, status: str = None) -> List[Dict[str, Any]]:
        """
        列出所有分析结果
        
        Args:
            status: 过滤状态，如果为None则返回所有
            
        Returns:
            List[Dict[str, Any]]: 结果摘要列表
        """
        index_data = self._load_index()
        results = []
        
        for video_id, result_info in index_data.get("results", {}).items():
            # 如果指定了状态，进行过滤
            if status:
                result_path = result_info.get("latest_path", "")
                result_status = result_path.split(os.sep)[-2] if os.sep in result_path else ""
                if result_status != status:
                    continue
            
            # 创建摘要信息
            summary = {
                "video_id": video_id,
                "latest_analysis_time": result_info.get("updated_at"),
                "total_analyses": len(result_info.get("history", [])),
                "latest_path": result_info.get("latest_path")
            }
            
            # 尝试加载最新结果的一些关键信息
            try:
                latest_result = self.load_analysis_result(video_id)
                if latest_result:
                    summary["status"] = latest_result.get("status")
                    summary["overall_confidence"] = latest_result.get("overall_confidence")
                    summary["analysis_time"] = latest_result.get("analysis_time")
            except:
                pass
            
            results.append(summary)
        
        # 按最后更新时间倒序排序
        results.sort(key=lambda x: x.get("latest_analysis_time", ""), reverse=True)
        
        return results
    
    def export_results_report(self, output_path: str = None) -> str:
        """
        导出结果报告
        
        Args:
            output_path: 输出路径
            
        Returns:
            str: 报告内容
        """
        # 获取所有结果
        all_results = self.list_all_results()
        
        # 按状态统计
        status_count = {}
        for result in all_results:
            status = result.get("status", "unknown")
            status_count[status] = status_count.get(status, 0) + 1
        
        # 计算总体置信度
        confidences = []
        for result in all_results:
            if "overall_confidence" in result and result["overall_confidence"] is not None:
                confidences.append(result["overall_confidence"])
        
        avg_confidence = sum(confidences) / len(confidences) if confidences else 0
        
        # 生成报告
        report = []
        report.append("视频分析结果报告")
        report.append("==================")
        report.append("")
        
        report.append("【统计摘要】")
        report.append(f"总分析视频数: {len(all_results)}")
        report.append(f"平均置信度: {avg_confidence:.1f}%")
        report.append("按状态统计:")
        for status, count in status_count.items():
            report.append(f"  - {status}: {count}个")
        report.append("")
        
        report.append("【分析记录列表】")
        report.append("视频ID | 状态 | 分析时间 | 置信度")
        report.append("-------|------|----------|--------")
        
        for result in all_results:
            video_id = result.get("video_id", "-")
            status = result.get("status", "-")
            analysis_time = result.get("analysis_time", "-")
            confidence = result.get("overall_confidence", "-")
            
            report.append(f"{video_id[:15]:<7} | {status:<4} | {analysis_time:<10} | {confidence}%")
        
        report_text = "\n".join(report)
        
        # 保存报告
        if output_path:
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(report_text)
            print(f"结果报告已导出: {output_path}")
        
        return report_text
    
    def backup_results(self, backup_dir: str = None) -> str:
        """
        备份所有结果
        
        Args:
            backup_dir: 备份目录，如果为None则自动生成
            
        Returns:
            str: 备份目录路径
        """
        # 生成备份目录
        if backup_dir is None:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            backup_dir = os.path.join(
                os.path.dirname(self.storage_dir), 
                f"backup_{timestamp}"
            )
        
        try:
            # 复制整个结果目录
            if os.path.exists(self.storage_dir):
                shutil.copytree(self.storage_dir, backup_dir)
                
                # 创建备份信息文件
                backup_info = {
                    "backup_time": datetime.now().isoformat(),
                    "source_dir": self.storage_dir,
                    "backup_dir": backup_dir,
                    "total_results": len(self.list_all_results())
                }
                
                backup_info_path = os.path.join(backup_dir, "backup_info.json")
                with open(backup_info_path, 'w', encoding='utf-8') as f:
                    json.dump(backup_info, f, ensure_ascii=False, indent=2)
                
                print(f"结果备份完成: {backup_dir}")
                return backup_dir
        except Exception as e:
            print(f"备份失败: {str(e)}")
            raise
    
    def _update_index(self, video_id: str, result_path: str, status: str):
        """
        更新索引
        
        Args:
            video_id: 视频ID
            result_path: 结果文件路径
            status: 状态
        """
        index_data = self._load_index()
        results = index_data.get("results", {})
        
        # 创建或更新结果条目
        if video_id not in results:
            results[video_id] = {
                "created_at": datetime.now().isoformat(),
                "updated_at": datetime.now().isoformat(),
                "latest_path": result_path,
                "history": []
            }
        else:
            # 如果最新路径不同，添加到历史记录
            current_latest = results[video_id].get("latest_path")
            if current_latest and current_latest != result_path:
                # 检查文件是否存在
                if os.path.exists(current_latest):
                    # 获取当前状态
                    current_status = current_latest.split(os.sep)[-2] if os.sep in current_latest else "unknown"
                    
                    # 添加到历史记录
                    results[video_id]["history"].insert(0, {
                        "path": current_latest,
                        "status": current_status,
                        "created_at": results[video_id].get("updated_at")
                    })
                
            # 更新最新路径
            results[video_id]["latest_path"] = result_path
            results[video_id]["updated_at"] = datetime.now().isoformat()
        
        # 添加当前结果到历史
        results[video_id]["history"].insert(0, {
            "path": result_path,
            "status": status,
            "created_at": datetime.now().isoformat()
        })
        
        # 更新索引
        index_data["results"] = results
        index_data["total_results"] = len(results)
        self._save_index(index_data)
    
    def find_results_by_date_range(self, start_date: str, end_date: str) -> List[Dict[str, Any]]:
        """
        按日期范围查找结果
        
        Args:
            start_date: 开始日期 (YYYY-MM-DD)
            end_date: 结束日期 (YYYY-MM-DD)
            
        Returns:
            List[Dict[str, Any]]: 匹配的结果列表
        """
        # 转换为datetime对象
        start_dt = datetime.strptime(start_date, "%Y-%m-%d")
        end_dt = datetime.strptime(end_date, "%Y-%m-%d")
        # 设置结束日期为当天的最后一刻
        end_dt = end_dt.replace(hour=23, minute=59, second=59)
        
        # 获取所有结果
        all_results = self.list_all_results()
        
        # 过滤日期范围内的结果
        filtered_results = []
        for result in all_results:
            analysis_time_str = result.get("analysis_time")
            if analysis_time_str:
                try:
                    # 尝试解析时间
                    analysis_dt = datetime.strptime(analysis_time_str, "%Y-%m-%d %H:%M:%S")
                    if start_dt <= analysis_dt <= end_dt:
                        filtered_results.append(result)
                except:
                    pass
        
        return filtered_results


# 使用示例
if __name__ == '__main__':
    try:
        # 创建结果管理器实例
        manager = AnalysisResultManager("./analysis_results")
        
        # 示例：创建一个测试结果
        test_result = {
            "video_id": "test_video_001",
            "analysis_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "scene_setting": {
                "option": "校园场景",
                "confidence": 85,
                "reasoning": "视频中出现了明显的校园建筑和学生"
            },
            "audio_material": {
                "option": "博主原声",
                "confidence": 90,
                "reasoning": "清晰的人声讲解"
            },
            "overall_confidence": 87,
            "status": "completed"
        }
        
        # 保存测试结果
        # result_path = manager.save_analysis_result("test_video_001", test_result)
        # print(f"测试结果已保存到: {result_path}")
        
        # 加载测试结果
        # loaded_result = manager.load_analysis_result("test_video_001")
        # if loaded_result:
        #     print("\n加载的测试结果:")
        #     print(f"视频ID: {loaded_result.get('video_id')}")
        #     print(f"总体置信度: {loaded_result.get('overall_confidence')}%")
        
        # 更新测试结果
        # updates = {
        #     "emotional_tendency": {
        #         "option": "积极正向",
        #         "confidence": 82,
        #         "reasoning": "整体氛围积极向上"
        #     }
        # }
        # updated_path = manager.update_analysis_result("test_video_001", updates)
        # print(f"\n测试结果已更新到: {updated_path}")
        
        # 列出所有结果
        # all_results = manager.list_all_results()
        # print(f"\n所有分析结果数量: {len(all_results)}")
        
        print("分析结果管理器初始化成功!")
        print("请在实际使用时，提供有效的视频ID和分析结果进行管理。")
        
    except Exception as e:
        print(f"初始化失败: {str(e)}")